local desc_joy1v1 = [[
  # 无尽单挑模式简介

  限两人游玩，玩家选择起始武将并和将池中所有武将进行单挑，直到将池耗尽或玩家认输。
  选将框最多14张
  (武将重新上场时，会触发一次所有游戏开始时可触发的技能)
  ___

  并不会获得额外技能什么的，仅仅只是普通的单挑。

  ___

  2024/11/9 更新：玩家处于休整状态时将不再判定增加负场，且换将后将根据武将牌正常获得护甲值

]]

-- FIXME: Disable same convert by param or extra data
local function rm(generals, gen)
  if type(gen) == "string" then
    gen = {gen}
  end
  for _, g in ipairs(gen) do
    local gt = Fk.generals[g].trueName
    for i, v in ipairs(generals) do
      if Fk.generals[v].trueName == gt then
        table.remove(generals, i)
        return
      end
    end
  end
end

local joy1v1_getLogic = function()
  local joy1v1_logic = GameLogic:subclass("joy1v1_logic")

  function joy1v1_logic:assignRoles()
    local room = self.room
    local n = #room.players
    local roles = self.role_table[n]
    table.shuffle(roles)

      --默认主反模式
      for i = 1, n do
        local p = room.players[i]
        p.role = roles[i]
        p.role_shown = true
        room:broadcastProperty(p, "role")
      end
  end

  function joy1v1_logic:chooseGenerals()
    local room = self.room ---@type Room
    local n = math.min(room.settings.generalNum,14)
    local m = room.settings.enableDeputy and 2 or 1
    table.removeOne(room.general_pile,"js__xushao")
    local lord = room.players[1]
    room.current = lord
    local nonlord = room.players[2]

    local lord_generals = room:getNGenerals(n)
    local nonlord_generals = room:getNGenerals(n)
    if room.settings.enableFreeAssign then
      lord.request_data = json.encode({ lord_generals, m })
      lord.default_reply = table.random(lord_generals,m)
      nonlord.request_data = json.encode { nonlord_generals, m }
      nonlord.default_reply = table.random(nonlord_generals,m)

      room:doBroadcastRequest("AskForGeneral", room.players)
      for _, p in ipairs(room.players) do
        local tab = p == lord and lord_generals or nonlord_generals
        if p.general == "" and p.reply_ready then
          local general = json.decode(p.client_reply)[1]
          room:setPlayerGeneral(p, general, true, true)
          if room.settings.enableDeputy then
            local deputy = json.decode(p.client_reply)[2]
            room:setDeputyGeneral(p, deputy)
          end
        else
          room:setPlayerGeneral(p, p.default_reply[1], true, true)
          if room.settings.enableDeputy then
            room:setDeputyGeneral(p, p.default_reply[2])
          end
        end
        p.default_reply = ""
      end
    else
      lord.request_data = json.encode({
        path = "packages/utility/qml/ChooseGeneralsAndChoiceBox.qml",
        data = {
          lord_generals,{"ok"}, "选择起始武将", false,m,m
        },
      })
      lord.default_reply = table.random(lord_generals,m)
      nonlord.request_data = json.encode({
        path = "packages/utility/qml/ChooseGeneralsAndChoiceBox.qml",
        data = {
          nonlord_generals,{"ok"}, "选择起始武将", false,m,m
        },
      })
      nonlord.default_reply = table.random(nonlord_generals,m)
          --choice = reply.cards[1]
      room:notifyMoveFocus(room.players, "选择武将")
      room:doBroadcastRequest("CustomDialog",room.players)
      for _, p in ipairs(room.players) do
        local tab = p == lord and lord_generals or nonlord_generals
        if p.general == "" and p.reply_ready then
          local general = json.decode(p.client_reply).cards
          room:setPlayerGeneral(p, general[1], true, true)
          if #general > 1 then
            room:setDeputyGeneral(p, general[2])
          end
        else
          room:setPlayerGeneral(p, p.default_reply[1], true, true)
          if #p.default_reply > 1 then
            room:setDeputyGeneral(p, p.default_reply[2])
          end
        end
        p.default_reply = ""
      end
    end
    

    for _, p in ipairs(room.players) do
      room:setPlayerProperty(p, "role_shown", true)
      room:broadcastProperty(p, "role")
    end
    room:broadcastProperty(lord, "general")
    room:broadcastProperty(nonlord, "general")
    room:broadcastProperty(lord, "kingdom")
    room:broadcastProperty(nonlord, "kingdom")
    room:setBanner("@&Allgenerals", {lord.general,nonlord.general})
    room:setBanner("@lordwin",0)
    room:setBanner("@nonlordwin",0)
    room:returnToGeneralPile(nonlord_generals)
    room:returnToGeneralPile(lord_generals)
    table.removeOne(room.general_pile,nonlord.general)
    table.removeOne(room.general_pile,lord.general)
    table.removeOne(room.general_pile,nonlord.deputyGeneral)
    table.removeOne(room.general_pile,lord.deputyGeneral)
    room:askForChooseKingdom(room.players)
  end

  return joy1v1_logic
end

--起始手牌
local function drawInit(room, player, n)
  -- TODO: need a new function to call the UI
  local cardIds = room:getNCards(n)
  player:addCards(Player.Hand, cardIds)
  for _, id in ipairs(cardIds) do
    Fk:filterCard(id, player)
  end
  local move_to_notify = {}   ---@type CardsMoveStruct
  move_to_notify.toArea = Card.PlayerHand
  move_to_notify.to = player.id
  move_to_notify.moveInfo = {}
  move_to_notify.moveReason = fk.ReasonDraw
  for _, id in ipairs(cardIds) do
    table.insert(move_to_notify.moveInfo,
    { cardId = id, fromArea = Card.DrawPile })
  end
  room:notifyMoveCards(nil, {move_to_notify})

  for _, id in ipairs(cardIds) do
    room:setCardArea(id, Card.PlayerHand, player.id)
  end
end

--游戏开始时机技能
local function restart(player)
  local skills = {}
  for _, s in ipairs(Fk.generals[player.general]:getSkillNameList()) do
    local s2 = Fk.skills[s]
    table.insertIfNeed(skills,s2)
    for _, s3 in ipairs(s2.related_skills) do
      table.insertIfNeed(skills,s3)
    end
  end
  if player.deputyGeneral and player.deputyGeneral ~= "" then
    for _, s in ipairs(Fk.generals[player.deputyGeneral]:getSkillNameList()) do
      local s2 = Fk.skills[s]
      table.insertIfNeed(skills,s2)
      for _, s3 in ipairs(s2.related_skills) do
        table.insertIfNeed(skills,s3)
      end
    end
  end
  for _, s in ipairs(skills) do
    if s:isInstanceOf(TriggerSkill) and type(s.events) == "table" and (table.contains(s.events,fk.GameStart) or table.contains(s.events, fk.GamePrepared)) then
      local events = {fk.GamePrepared}
      for i = #events, 1, -1 do
        if not table.contains(s.events, events[i]) then
          table.remove(events, i)
        end
      end
      for _, e in ipairs(events) do
        if s:triggerable(e, player, player, nil) then
          s:trigger(e, player, player, nil)
        end
      end
    end
  end
  local draw_data = { num = 4 }
  player.room.logic:trigger(fk.DrawInitialCards, player, draw_data)
  drawInit(player.room, player, draw_data.num)
  player.room.logic:trigger(fk.AfterDrawInitialCards, player, draw_data)
  for _, s in ipairs(skills) do
    if s:isInstanceOf(TriggerSkill) and type(s.events) == "table" and (table.contains(s.events,fk.GameStart) or table.contains(s.events, fk.GamePrepared)) then
      local events = {fk.GameStart}
      for i = #events, 1, -1 do
        if not table.contains(s.events, events[i]) then
          table.remove(events, i)
        end
      end
      for _, e in ipairs(events) do
        if s:triggerable(e, player, player, nil) then
          s:trigger(e, player, player, nil)
        end
      end
    end
  end
end

--重选武将
local function change(player)
  local room = player.room 
  local n = math.min(14,room.settings.generalNum)
  local m = room.settings.enableDeputy and 2 or 1

  local lord = player
  local lord_generals = room:getNGenerals(math.min(n,#room.general_pile))
  local gen,deputy
      lord.request_data = json.encode({
        path = "packages/utility/qml/ChooseGeneralsAndChoiceBox.qml",
        data = {
          lord_generals,{"ok"}, room.settings.enableDeputy and "选择主副将" or"选择武将" , false,m,m
        },
      })
      lord.default_reply = table.random(lord_generals,m)
      
      room:notifyMoveFocus({lord}, "选择武将")
      room:doBroadcastRequest("CustomDialog",{lord})
      for _, p in ipairs({lord}) do
        local tab =  lord_generals 
        if  p.reply_ready then
          gen = json.decode(p.client_reply).cards
          rm(tab, gen)
        else
          gen = p.default_reply
        end
        p.default_reply = ""
      end
      if #gen > 1 then
        deputy = gen[2]
      end
      gen = gen[1]
  local p = player
  local noto_rm = table.filter(p.player_skills, function(s)
      return not s.attached_equip  and s.name[#s.name] ~= "&" -- 不是装备技和按钮的全图图了
    end)
    local rmskill = {"jjj__huoji&","jjj__lianhuan&","jjj__yeyan&","jj__yeyan&","jj__huoji&","jj__lianhuan&",}
  room:handleAddLoseSkills(player, "-"..table.concat(rmskill, "|-"), nil)
  room:handleAddLoseSkills(p, table.concat(table.map(noto_rm, function(s) return "-" .. s.name end), "|"), nil, true)
  room:resumePlayerArea(p,  p.sealedSlots) -- 全部恢复
  local ban = room:getBanner("@&Allgenerals") or {}
  table.insertIfNeed(ban,gen)
  room:changeHero(p,gen, false, false, true,true)
  room:broadcastProperty(p,"kingdom")
  if room.settings.enableDeputy then 
    table.insertIfNeed(ban,deputy)
    room:changeHero(p,deputy, false,true, true,true)
  end
  room:setBanner("@&Allgenerals",ban)
  room:revivePlayer(p, false)
  if type(lord_generals) == "table" and  #lord_generals > 0 then
  room:returnToGeneralPile(lord_generals)
  end
  table.removeOne(room.general_pile,lord.general)
  if room.settings.enableDeputy then 
    room:setPlayerProperty(p, "hp", (Fk.generals[gen].hp + Fk.generals[deputy].hp)//2)
    room:setPlayerProperty(p, "shield", ((Fk.generals[gen].shield or 0) + (Fk.generals[deputy].shield or 0))//2)
    table.removeOne(room.general_pile,lord.deputyGeneral)
  else
    room:setPlayerProperty(p, "hp", Fk.generals[gen].hp)
    room:setPlayerProperty(p, "shield", Fk.generals[gen].shield or 0)
  end
  restart(p)
end


local joy1v1_rule = fk.CreateTriggerSkill{
  name = "#joy1v1_rule",
  priority = 0.001,
  refresh_events = {fk.DrawInitialCards, fk.GameOverJudge, fk.BuryVictim, fk.GameStart},
  can_refresh = function(self, event, target, player, data)
    return target == player
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    local body
    local m = room.settings.enableDeputy and 2 or 1
    if event == fk.BuryVictim or event == fk.GameOverJudge then
      body = room:getPlayerById(data.who)
    end
    if event == fk.DrawInitialCards then
      local roundCount = room:getTag("RoundCount")
      if roundCount > 0 then return end
      if player.role == "lord" then
        data.num = 3
      else
        data.num = 5
      end
    elseif event == fk.GameOverJudge then
      room:setTag("SkipGameRule", true)
      if   #room.general_pile >= m  then return end
      local a = room:getBanner("@lordwin") or 0
      local b = room:getBanner("@nonlordwin") or 0
      if a > b then
        room:doBroadcastNotify("ShowToast", "先手玩家已 "..a..":"..b.." 的战绩赢得游戏！")
        room:gameOver("lord")
      elseif b > a then
        room:doBroadcastNotify("ShowToast", "后手玩家已 "..b..":"..a.." 的战绩赢得游戏！")
        room:gameOver("nonlord")
      else
        room:doBroadcastNotify("ShowToast", "游戏平局，最终战绩 "..a..":"..b.." 。")
        room:gameOver("")
      end
      ---玩家死亡换将
    elseif event == fk.BuryVictim  then
      room:setTag("SkipGameRule", true)
      body:bury()
      if body.rest > 0 then return end
      if body.role == "lord" then
        room:doBroadcastNotify("ShowToast", "后手胜场+1")
        room:setBanner("@nonlordwin",(room:getBanner("@nonlordwin") or 0) + 1)
      else
        room:doBroadcastNotify("ShowToast", "先手胜场+1")
        room:setBanner("@lordwin",(room:getBanner("@lordwin") or 0 )+ 1)
      end
      local current = room.logic:getCurrentEvent()
      local last_event = nil
      if room.current.dead then
        last_event = current:findParent(GameEvent.Turn, true)
      end
      if last_event == nil then
        last_event = current
        if last_event.parent then
          repeat
            if table.contains({GameEvent.Round, GameEvent.Turn, GameEvent.Phase}, last_event.parent.event) then break end
            last_event = last_event.parent
          until (not last_event.parent)
        end
      end
      last_event:addExitFunc(function()
        change(body)
        --room.logic:breakTurn()
        room.current:endPlayPhase()
      end)
    end
  end,
}
local joy1v1_mode = fk.CreateGameMode{
  name = "joy1v1_mode",
  minPlayer = 2,
  maxPlayer = 2,
  rule = joy1v1_rule,
  logic = joy1v1_getLogic,
  surrender_func = function(self, playedTime)
    return { { text = "joy1v1_allcan", passed = true } }
  end,
}

Fk:loadTranslationTable{
  ["joy1v1_mode"] = "无尽单挑",
  ["@&Allgenerals"] = "已抽武将",
  ["@lordwin"] = "先手胜场",
  ["@nonlordwin"] = "后手胜场",
  ["joy1v1_allcan"] = "你随时都可以投降",
  ["CustomDialog"] = "选项框",
  

  [":joy1v1_mode"] = desc_joy1v1,
}

return joy1v1_mode
